package kr.re.etri.snsenabler.server.db;

import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;

import kr.re.etri.snsenabler.shared.Data;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SnsEnablerDbService {
	private static final String CONFIG_RESOURCE = "kr/re/etri/snsenabler/server/db/SnsEnablerSqlMapConfig.xml";

	private static final Logger logger = Logger.getLogger(SnsEnablerDbService.class.getName());

	static {
		org.apache.ibatis.logging.LogFactory.useJdkLogging();
	}

	private final SqlSessionFactory sqlSessionFactory;

	public SnsEnablerDbService() throws IOException {
		super();

		Reader configReader = Resources.getResourceAsReader(CONFIG_RESOURCE);
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(configReader, "SnsEnabler");

		initialzie();
	}

	private void initialzie() {
		SqlSession session = sqlSessionFactory.openSession();

		try {
//			session.update("dropUserTable");
			session.update("createUserTable");
//			session.update("dropOAuthSnsTable");
			session.update("createOAuthSnsTable");
			session.commit();
		} catch (Exception e) {
			logger.log(Level.SEVERE, e.getMessage(), e);
			session.rollback();
		} finally {
			session.close();
		}
	}

	public Data getUser(String loginId) {
		SqlSession session = sqlSessionFactory.openSession(true);

		try {
			@SuppressWarnings("unchecked")
			HashMap<String, Object> selected = (HashMap<String, Object>)session.selectOne("selectUserByLoginId", loginId);

			if (selected == null) {
				return null;
			} else {
				return new Data(selected);
			}
		} finally {
			session.close();
		}
	}

	public void insertUser(Data data) throws Exception {
		SqlSession session = sqlSessionFactory.openSession(false);

		try {
			session.insert("insertUser", data);
			session.commit();
		} catch (Exception e) {
			session.rollback();
			throw e;
		} finally {
			session.close();
		}
	}

	public ArrayList<Data> getSocialServiceProviders(String loginId) {
		ArrayList<Data> providers = new ArrayList<Data>();
		ArrayList<Data> oAuth1Providers = getOAuthSocialServiceProviders(loginId);
		providers.addAll(oAuth1Providers);
		return providers;
	}

	private ArrayList<Data> getOAuthSocialServiceProviders(String loginId) {
		SqlSession session = sqlSessionFactory.openSession(true);
		ArrayList<Data> providers = new ArrayList<Data>();

		try {
			@SuppressWarnings("unchecked")
			ArrayList<HashMap<String, Object>> selectedList = (ArrayList<HashMap<String, Object>>)session.selectList("selectOAuthSocialServices", loginId);

			if (selectedList != null && !selectedList.isEmpty()) {
				for (int i = 0; i < selectedList.size(); i++) {
					providers.add(new Data(selectedList.get(i)));
				}
			}
		} finally {
			session.close();
		}
		return providers;
	}

	public void insertOAuthSocialService(Data data) throws Exception {
		SqlSession session = sqlSessionFactory.openSession(false);

		try {
			session.insert("insertOAuthSocialService", data);
			session.commit();
		} catch (Exception e) {
			session.rollback();
			throw e;
		} finally {
			session.close();
		}
	}
}
